package cn.jofei.client.netty;

import cn.jofei.client.netty.handler.ServiceMessageHandler;
import cn.jofei.common.netty.protocol.ProtocolFrameDecoder;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;

/**
 * 服务端连接器
 *
 * @author Jofei Bao
 * @version ngbao v2.0
 * @date 2022年10月18日 11:29
 */
public class SocketServerConnector extends SocketClient {
    /**
     * 服务端消息处理器
     */
    private static final ServiceMessageHandler MESSAGE_HANDLER = new ServiceMessageHandler();

    @Override
    public void start() {
        try {
            ChannelFuture future = newServerChannelFuture(MESSAGE_HANDLER);
            future.addListener(promise -> {
                if (!promise.isSuccess()) {
                    logger.error("创建连接时异常,{}", promise.cause().getMessage());
                }
            });
        } catch (Exception e) {
            logger.error("创建连接异常,{}", e.getMessage());
        }
    }

    public static ChannelFuture newServerChannelFuture() {
        return newServerChannelFuture(null);
    }

    public static ChannelFuture newServerChannelFuture(ChannelHandler handler) {
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(WORK_GROUP)
                .channel(NioSocketChannel.class)
                // 客户端 连接配置项
                .option(ChannelOption.SO_KEEPALIVE, true)
                .option(ChannelOption.AUTO_READ, false)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel sc) throws Exception {
                        sc.pipeline()
                                .addLast(new ProtocolFrameDecoder())
                                .addLast(LOGGING_HANDLER)
                                // 心跳监测
                                .addLast(new IdleStateHandler(0, 2, 0))
                                .addLast(MESSAGE_CODEC);
                        if (handler != null) {
                            sc.pipeline().addLast(handler);
                        }
                    }
                });
        return bootstrap.connect(REMOTE_IP, SERVER_PORT);
    }

}
